﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace DM4Script
{
    public partial class ScriptParse
    {
        private bool HandleRun()
        {
            if ((RunSection = ParseRun()) != null)
                LogAdd("Parsed RUN section - OK");
            else
                GetNextToken(); // Пропускаем токен для восстановления после ошибки.

            return RunSection != null;
        }

        /// prototype
        ///  ON taskName1,...: IF(...) taskName2
        private Prototypes.RunSection ParseRun()
        {
            GetNextToken();

            // Считываем список TASKs
            var tasksRun = new Queue<Prototypes.TaskRun>();

            if (_curTok != (char)Token.RunTask)
                return ErrorRun("Expected ON in prototype RUN");

            while (true)
            {
                Prototypes.TaskRun taskRun = ParseTaskRun();
                if (taskRun == null) return null;

                tasksRun.Enqueue(taskRun);

                if (_curTok != (char) Token.RunTask) break;
            }

            return new Prototypes.RunSection(tasksRun);
        }

        /// prototype
        /// ON taskName1,...: IF(...) taskName2
        private Prototypes.TaskRun ParseTaskRun()
        {
            var tasksOn = new Dictionary<string, Prototypes.ScriptTask>();
            Prototypes.ExprAst runComand;

            while (true)
            {
                GetNextToken();

                if (_curTok != (char)Token.Identifier)
                    return ErrorTaskRun("Expected TASK name in prototype");

                string taskName = _identifierStr.ToUpperInvariant();

                if (Declare == null || !Declare.Tasks.ContainsKey(taskName))
                    return ErrorTaskRun(String.Format("ScriptTask name '{0}' is not found DECLATE", taskName));

                tasksOn.Add(taskName, Declare.Tasks[taskName]);

                GetNextToken();
                if (_curTok != ',' && _curTok != ':')
                    return ErrorTaskRun("Expected ',' or ':' in prototype");

                if (_curTok == ':') break;
            }
            
            GetNextToken();

            if(_curTok == (char)Token.If)
            {
                if ((runComand = ParseIfExpr(new Queue<string>(from tasksExists in tasksOn select tasksExists.Key))) == null) return null;
            }
            else
            {
                runComand = ParsesCommands();
                if (runComand == null) return null;

                //if (_curTok != (char) Token.Identifier)
                //    return ErrorTaskRun("Expected TASK or SUBTASK name in prototype");

                //string taskName = _identifierStr.ToUpperInvariant();

                //if (!Declare.ScriptTask.ContainsKey(taskName))
                //    return ErrorTaskRun(String.Format("ScriptTask name '{0}' is not declare", taskName));

                //runComand = Declare.ScriptTask[taskName];
            }

            return new Prototypes.TaskRun(tasksOn, runComand);
        }
    }
}
